package cn.tedu.charging.cost.service.impl;

import cn.tedu.charging.common.pojo.param.ProgressCostParam;
import cn.tedu.charging.common.pojo.po.ChargingCostRulePO;
import cn.tedu.charging.common.pojo.vo.ProgressCostVO;
import cn.tedu.charging.cost.repository.CostRuleRepository;
import cn.tedu.charging.cost.service.CostService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Calendar;
import java.util.Date;

@Service
@Slf4j
public class CostServiceImpl implements CostService {
    @Autowired
    private CostRuleRepository costRuleRepository;
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public ProgressCostVO calculateCost(ProgressCostParam param) {
        //1.获取当前系统时间
        Integer hour=getCurrentHours();
        log.debug("当前时间：{}",hour);
        //2.查询计价规则 stationId hour
        ChargingCostRulePO rule=getCurrentCostRule(param.getStationId(),hour);
        log.debug("当前规则：{}",rule);
        //准备2个值 一个总金额 一个单次度数
        Double totalCost=null;
        Double capacity=null;
        //3.根据首付是第一次计算价格,计算单次度数,使用计价规则乘以单次度数,加上上次的金额得到本次总金额
        ValueOperations stringOps = redisTemplate.opsForValue();
        //3.1使用存储该订单到目前为止的总度数 key set key 本地总度数 GET(如果是第一次前面没值) 返回值null
        String orderTotalCapacityKey="charging:order:total:capacity:"+param.getOrderNo();
        Double oldTotalCapacity = (Double) stringOps.getAndSet(orderTotalCapacityKey,param.getTotalCapacity());
        //3.2判断 上次的总金额是否是空 来解决第一次的问题
        if (oldTotalCapacity==null){
            //第一次 同步 单次度数就等于同步过来的总度数
            capacity=param.getTotalCapacity();
        }else{
            //不是第一次 同步 单次度数就等本次总度数 减去上次总度数
            capacity=param.getTotalCapacity()-oldTotalCapacity;
        }
        //4.得到单次度数,知道单价之后,我可以计算本次充电金额,做叠加处理 incr命令
        String totalCostKey="charging:total:cost:"+param.getOrderNo();
        totalCost=stringOps.increment(totalCostKey,capacity*rule.getPowerFee().doubleValue());
        //5.使用上述计算结果封装vo返回数据
        ProgressCostVO vo=new ProgressCostVO();
        vo.setTotalCost(totalCost);
        vo.setPowerFee(rule.getPowerFee().doubleValue());
        vo.setChargingCapacity(capacity);
        return vo;
    }

    private ChargingCostRulePO getCurrentCostRule(Integer stationId, Integer hour) {
        //计价规则costRule 存储在数据库 应该将条件交给repository,读取数据层信息
        return costRuleRepository.getCostRule(stationId,hour);
    }

    private Integer getCurrentHours() {
        //方案1: Date api
        //return new Date().getHours();
        //方案2: Calendar api
        //return Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
        //方案3: LocalDateTime
        return LocalDateTime.now().getHour();
    }
}
